import {readFile} from "@tauri-apps/plugin-fs";

interface IColor {
    r: number;
    g: number;
    b: number;
}

export class CursorB64 {
    value: string = "";
    centerX: number = 0;
    centerY: number = 0;
}

export async function loadCurFileToBase64(uri: string) {
    const ui8 = await readFile(uri);
    const buffer = ui8.buffer;
    const header = new DataView(buffer.slice(0, 6));
    const dir = new DataView(buffer.slice(6, 22));
    const imageDataOffset = dir.getUint32(12, true);
    const bmpHeader = new DataView(buffer.slice(imageDataOffset, imageDataOffset + 40));
    const imageBuffer = new DataView(buffer.slice(imageDataOffset + 40));
    const fileType = header.getUint16(2, true);
    const imageContain = header.getUint16(4, true);
    if (fileType != 2 || imageContain == 0) {
        throw new Error(`File is not typeof cur or contains no image data.`);
    }
    const width = dir.getUint8(0);
    const height = dir.getUint8(1);
    const palletColorCount = bmpHeader.getUint32(32, true);
    const colorPallet: IColor[] = [];
    for (let i = 0; i < palletColorCount; i++) {
        const offset = i * 4;
        const b = imageBuffer.getUint8(offset);
        const g = imageBuffer.getUint8(offset + 1);
        const r = imageBuffer.getUint8(offset + 2);
        colorPallet.push({r, g, b});
    }
    const bytesPerRow = Math.ceil(width / 8);
    const paddedBytesPerRow = bytesPerRow + (4 - (bytesPerRow % 4)) % 4;
    const imageDataClamped = new Uint8ClampedArray(4 * width * height);
    const pixelOffset = palletColorCount * 4;
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const byteIndex = Math.floor(x / 8);
            const bitIndex = 7 - (x % 8);
            const byte = imageBuffer.getUint8(pixelOffset + y * paddedBytesPerRow + byteIndex);
            const pixelValue = (byte >> bitIndex) & 1;
            const color = colorPallet[pixelValue];
            if (color == undefined) continue;
            const imageDataOffset = ((height - y - 1) * width + x) * 4;
            imageDataClamped[imageDataOffset] = color.r;
            imageDataClamped[imageDataOffset + 1] = color.g;
            imageDataClamped[imageDataOffset + 2] = color.b;
            if (pixelValue == 0)
                imageDataClamped[imageDataOffset + 3] = 0;
            else
                imageDataClamped[imageDataOffset + 3] = 255;
        }
    }
    const imageData = new ImageData(imageDataClamped, width, height);
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    if (ctx == null) throw new Error("Can't load context from canvas");
    canvas.width = width;
    canvas.height = height;
    ctx.putImageData(imageData, 0, 0);
    const d = new CursorB64();
    d.value = canvas.toDataURL("image/png");
    d.centerX = width / 2;
    d.centerY = height / 2;
    return d;
}